package ru.msu.cmc.sp.oberon2;

import antlr.RecognitionException;

public class Symbol {
    String name;
    Type type;
    Scope scope;
    InterAST def;
    String value;
    boolean array, constant = false;

    public Symbol(String name) {
    	this.name = name;
    	}
    public Symbol(String name, Type type) {
    	this(name); this.type = type; 
    	}
    
    public Symbol(String name, Type type, Scope parent) {
    	this(name);
    	this.type = type;
    	this.scope = parent;
    	}
    
    public Symbol(Symbol s, String namearg){
    	name = namearg;
    	type = s.type;
    	scope = s.scope;
    	def = s.def;
    	value = s.value;
    	array = s.array;
    	constant = s.constant;
    }
    
    public String getName() {
    	return name; 
    	}
    
    public void plus(Symbol arg){
    	if (arg.type.isInt()){
    		value = ((Integer)(Integer.parseInt(value) + Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
    		value = ((Double)(Double.parseDouble(value) + Double.parseDouble(arg.value))).toString();
    	}
    }
    public void minus(Symbol arg){
    	if (arg.type.isInt()){
    		value = ((Integer)(Integer.parseInt(value) - Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
    		value = ((Double)(Double.parseDouble(value) - Double.parseDouble(arg.value))).toString();
    	}
    }
    public void mult(Symbol arg){
    	if (arg.type.isInt()){
    		value= ((Integer)(Integer.parseInt(value) * Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
    		value= ((Double)(Double.parseDouble(value) * Double.parseDouble(arg.value))).toString();
    	}
    }
    public void greater(Symbol arg){
    	if (arg.type.isInt()){
    		type = SymbolTable._boolean;
    		value = ((Boolean)(Integer.parseInt(value) > Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
        		type = SymbolTable._boolean;
        		value = ((Boolean)(Double.parseDouble(value) > Double.parseDouble(arg.value))).toString();
        }
    }
    public void greater_eq(Symbol arg){
    	if (arg.type.isInt()){
    		type = SymbolTable._boolean;
    		value = ((Boolean)(Integer.parseInt(value) >= Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
        		type = SymbolTable._boolean;
        		value = ((Boolean)(Double.parseDouble(value) >= Double.parseDouble(arg.value))).toString();
        }
    }
    public void less(Symbol arg){
    	if (arg.type.isInt()){
    		type = SymbolTable._boolean;
    		value = ((Boolean)(Integer.parseInt(value) < Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
        		type = SymbolTable._boolean;
        		value = ((Boolean)(Double.parseDouble(value) < Double.parseDouble(arg.value))).toString();
        }
    }
    public void less_eq(Symbol arg){
    	if (arg.type.isInt()){
    		type = SymbolTable._boolean;
    		value = ((Boolean)(Integer.parseInt(value) <= Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
        		type = SymbolTable._boolean;
        		value = ((Boolean)(Double.parseDouble(value) <= Double.parseDouble(arg.value))).toString();
        }
    }
    public void eq(Symbol arg){
    	if (arg.type.isInt()){
    		type = SymbolTable._boolean;
    		value = ((Boolean)(Integer.parseInt(value) == Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
        		type = SymbolTable._boolean;
        		value = ((Boolean)(Double.parseDouble(value) == Double.parseDouble(arg.value))).toString();
        }
    	else
    	if (!arg.type.isNumber()){
        		type = SymbolTable._boolean;
        		value = ((Boolean)(Boolean.parseBoolean(value) == Boolean.parseBoolean(arg.value))).toString();
        }
    		
    }
    public void div(Symbol arg){
    	if (arg.type.isInt()){
    		value= ((Integer)(Integer.parseInt(value) / Integer.parseInt(arg.value))).toString();
    	}else
    	if (arg.type.isReal()){
    		value= ((Double)(Double.parseDouble(value) / Double.parseDouble(arg.value))).toString();
    	}
    }
    public void mod(Symbol arg){
    	if (arg.type.isInt()){
    		value= ((Integer)(Integer.parseInt(value) % Integer.parseInt(arg.value))).toString();
    	}
    }
    public void not(){
    	if (!(type.isNumber())){
    		value = ((Boolean)(!Boolean.parseBoolean(value))).toString(); 
    	}
    }
    public void and(Symbol arg){
    	if (!(arg.type.isNumber())){
    		value= ((Boolean)(Boolean.parseBoolean(value) && Boolean.parseBoolean(arg.value))).toString();
    	}
    }
    public void or(Symbol arg){	
    	if (!(arg.type.isNumber())){
    		value = ((Boolean)(Boolean.parseBoolean(value) || Boolean.parseBoolean(arg.value))).toString();
    	}
    }
    public void assign(Symbol arg){
    	type = arg.type;
    	if (type.isInt() ||  type.isReal() || !(type.isNumber())){
    		value = arg.value;
    	}
    }
    public Symbol clone() {
    	return new Symbol(this, this.name);
    }
}
